package com.sybil.ot.servicio;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.sybil.ot.dao.PedidoDAO;
import com.sybil.ot.dominio.Factura;
import com.sybil.ot.dominio.OrdenTrabajo;
import com.sybil.ot.dominio.Pedido;
import com.sybil.ot.dominio.PedidoOrden;
import com.sybil.ot.dominio.Solicitud;
import com.sybil.ot.dominio.TrabajoRealizado;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service("pedidoServicio")
@Transactional(readOnly = true)
public class PedidoServicio {

   @Autowired
   private PedidoDAO pedidoDAO;
   @Autowired
   private SolicitudServicio solicitudServicio;
   @Autowired
   private OrdenTrabajoService ordenTrabajoService;

   public void guardar(Pedido pedido, boolean enviar) {
      pedido.getLlave().setSerie("A");
      pedido.setEstatus("AB");
      pedido.getLlave().setNumero(pedidoDAO.obtenerSecuencia(pedido.getLlave().getSerie()));
      if ("".equals(pedido.getProveedor().getNumero())) {
         pedido.setProveedor(null);
      }
      double totalPedido = 0;
      List<Factura> facturas = pedido.getFacturas();
      for (int i = 0; i < facturas.size(); i++) {
         facturas.get(i).getLlave().setNumero(i + 1);
         facturas.get(i).setUsuarioCreo(pedido.getUsuarioCreo());
         facturas.get(i).setPedido(pedido);
         if (pedido.getProveedor() == null) {
            facturas.get(i).setRazonSocial("Depto. Mtto y gestion AF");
         } else {
            facturas.get(i).setProveedor(pedido.getProveedor());
            facturas.get(i).setRazonSocial(" ");
         }
         totalPedido += facturas.get(i).getSubtotal() + facturas.get(i).getMontoIva();
         //set tipo de cambio
      }
      List<PedidoOrden> ordenes = pedido.getOrdenes();
      if (ordenes != null) {
         Iterator<PedidoOrden> i = ordenes.iterator();
         while (i.hasNext()) {
            PedidoOrden orden = i.next();
            int num = orden.getLlave().getNumeroOT();
            if (num == 0) {
               i.remove();
            } else {
//               orden.getClave().setSerieOT(serieOT.substring(0, 1));
//               orden.getClave().setNumeroOT(Integer.parseInt(serieOT.substring(1)));
               orden.getLlave().setSeriePe(pedido.getLlave().getSerie());
               orden.getLlave().setNumeroPe(pedido.getLlave().getNumero());
               orden.setUsuarioCreo(pedido.getUsuarioCreo());
            }
         }
         for (PedidoOrden pedidoOT : ordenes) {//cambia el estatus de las ot a "en pedido"
            ordenTrabajoService.actualizaEstatus(pedidoOT.getLlave().getSerieOT(), pedidoOT.getLlave().getNumeroOT(), "P");
         }
      }
      //manejo del archivo
      List<MultipartFile> anexosFactura = pedido.getAnexosFactura();
      for (int i = 0; i < anexosFactura.size(); i++) {
         String nombreAnexo = pedido.getLlave().getSerie() + "_"
                 + pedido.getLlave().getNumero() + "_FAC" + facturas.get(i).getLlave().getNumero()
                 + "_" + facturas.get(i).getLlave().getFolio();
         facturas.get(i).setRutaAnexo(guardarArchivo(anexosFactura.get(i), nombreAnexo));
      }

      if (enviar) {
         Solicitud solicitud = solicitudServicio.generarSolicitud(
                 pedido.getSolicitud().getFlujo().getClave(),
                 pedido.getUsuarioCreo(), totalPedido, pedido.getComentarios());
         solicitudServicio.guardar(solicitud);
         pedido.setEstatus("EA");
         pedido.setSolicitud(solicitud);
         try {
            pedidoDAO.guardarPedido(pedido);
         } catch (Exception e) {
            solicitudServicio.eliminarSolicitud(solicitud.getLlave().getClaveFlujo(), solicitud.getLlave().getNumeroSolicitud());
         }
      } else {
         pedido.setSolicitud(null);
         pedidoDAO.guardarPedido(pedido);
      }
   }

   public void editar(Pedido pedido, boolean enviar) {
      double totalPedido = 0;
      List<Factura> facturas = pedido.getFacturas();
      for (int i = 0; i < facturas.size(); i++) {
         facturas.get(i).setUsuarioModif(pedido.getUsuarioModif());
         facturas.get(i).setPedido(pedido);
         totalPedido += facturas.get(i).getSubtotal() + facturas.get(i).getMontoIva();
      }
      List<PedidoOrden> ordenes = pedido.getOrdenes();
      for (int i = 0; i < ordenes.size(); i++) {
         String serieOT = ordenes.get(i).getLlave().getSerieOT();
         ordenes.get(i).getLlave().setSerieOT(serieOT.substring(0, 1));
         ordenes.get(i).getLlave().setNumeroOT(Integer.parseInt(serieOT.substring(1)));
         ordenes.get(i).getLlave().setSeriePe(pedido.getLlave().getSerie());
         ordenes.get(i).getLlave().setNumeroPe(pedido.getLlave().getNumero());
         ordenes.get(i).setUsuarioModif(pedido.getUsuarioModif());
         if (pedido.getEstatus().equals("FI")) {
            //usuario modif
            ordenTrabajoService.actualizaEstatus(serieOT, ordenes.get(i).getLlave().getNumeroOT(), "F");
         } else if (pedido.getEstatus().equals("AN")) {
            ordenTrabajoService.actualizaEstatus(serieOT, ordenes.get(i).getLlave().getNumeroOT(), "X");
         }
      }
      if (enviar) {
         Solicitud solicitud = solicitudServicio.generarSolicitud(
                 pedido.getSolicitud().getFlujo().getClave(),
                 pedido.getUsuarioCreo(), totalPedido, pedido.getComentarios());
         solicitudServicio.guardar(solicitud);
         pedido.setEstatus("EA");
         pedido.setSolicitud(solicitud);
         try {
            pedidoDAO.editarPedido(pedido);
         } catch (Exception e) {
            solicitudServicio.eliminarSolicitud(solicitud.getLlave().getClaveFlujo(), solicitud.getLlave().getNumeroSolicitud());
         }
      } else {
         pedido.setSolicitud(null);
         pedidoDAO.editarPedido(pedido);
      }
//      pedidoDAO.editarPedido(pedido);
   }

   public void editarEstatus(Pedido pedido) {
      List<PedidoOrden> ordenes = pedido.getOrdenes();
      for (int i = 0; i < ordenes.size(); i++) {
         OrdenTrabajo ot = ordenes.get(i).getOrdenTrabajo();
         ot.setUsuarioModif(pedido.getUsuarioModif());
         if (pedido.getEstatus().equals("FI")) {
            ot.setEstatus("F");
         } else if (pedido.getEstatus().equals("AN")) {
            ot.setEstatus("X");
         }
         ordenTrabajoService.editar(ot);
      }
      pedidoDAO.editarPedido(pedido);
   }

   @Transactional(readOnly = false)
   public void eliminarPedido(String serie, int numero) {
      Pedido pedido = pedidoDAO.obtenerPedido(serie, numero);
      pedidoDAO.eliminarPedido(pedido);
   }

   public List<Pedido> obtenerPedidos() {
      return pedidoDAO.obtenerPedidos();
   }

   public Pedido obtenerPedidoSolicitud(String claveFlujo, int numeroSolicitud) {
      return pedidoDAO.obtenerPedidoSolicitud(claveFlujo, numeroSolicitud);
   }

   public Pedido obtenerPedido(String serie, int numero) {
      return pedidoDAO.obtenerPedido(serie, numero);
   }

   public String guardarArchivo(MultipartFile anexoOT, String nombre) {
      String nombreCompleto = "";
      if (!anexoOT.isEmpty()) {
         String extension = anexoOT.getOriginalFilename()
                 .substring(anexoOT.getOriginalFilename()
                         .lastIndexOf("."), anexoOT.getOriginalFilename().length());
         nombreCompleto = "C:\\TEMP_WEB\\ANEXO_PED_" + nombre + extension;
         FileOutputStream streamEscritura = null;
         InputStream archivo = null;
         try {
            archivo = anexoOT.getInputStream();
            streamEscritura = new FileOutputStream(nombreCompleto);
            byte[] buffer = new byte[1024];
            int leido = 0;
            while ((leido = archivo.read(buffer)) != -1) {
               streamEscritura.write(buffer, 0, leido);
            }
         } catch (IOException ex) {
            //tratar ex
            nombreCompleto = "";
            ex.getMessage();
         } finally {
            if (archivo != null) {
               try {
                  archivo.close();
               } catch (IOException ex) {
                  ex.getMessage();
               }
            }
            if (streamEscritura != null) {
               try {
                  streamEscritura.close();
               } catch (IOException ex) {
                  ex.getMessage();
               }
            }
         }
      }
      return nombreCompleto;
   }//finaliza el guardado del archivo

   public String generarPDF(String serie, int numero) {
      String rutaArchivoPDF = "C:\\TEMP_WEB\\PEDIDO_" + serie.trim() + "_" + numero + ".pdf";
      try {
         Pedido pedido = pedidoDAO.obtenerPedido(serie, numero);
         Document documentoPDF = new Document();
         PdfWriter writer = PdfWriter.getInstance(documentoPDF, new FileOutputStream(rutaArchivoPDF));
         documentoPDF.open();

         PdfPTable tablaDetallePedido = new PdfPTable(new float[]{1, 3, 1, 3});
         tablaDetallePedido.setWidthPercentage(100f);
         tablaDetallePedido.getDefaultCell().setUseAscender(true);
         tablaDetallePedido.getDefaultCell().setUseDescender(true);
         Font f = new Font();
         f.setColor(Color.WHITE);
         PdfPCell cell = new PdfPCell(new Phrase("Pedido No." + pedido.getLlave().getNumero(), f));
         cell.setBackgroundColor(Color.BLACK);
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(4);
         tablaDetallePedido.addCell(cell);
         tablaDetallePedido.getDefaultCell().setBackgroundColor(Color.WHITE);
         tablaDetallePedido.addCell("Numero:");
         tablaDetallePedido.addCell("" + pedido.getLlave().getNumero());
         tablaDetallePedido.addCell("Fecha:");
         tablaDetallePedido.addCell(pedido.getFecha().toString());
         tablaDetallePedido.addCell("Proveedor:");
         tablaDetallePedido.addCell(pedido.getProveedor().getRazonSocial());
         tablaDetallePedido.addCell("RFC:");
         tablaDetallePedido.addCell(pedido.getProveedor().getRfc());
         documentoPDF.add(tablaDetallePedido);

         PdfPTable tablaOrdenes = new PdfPTable(new float[]{3, 3, 3, 3});
         tablaOrdenes.setWidthPercentage(100f);
         tablaOrdenes.getDefaultCell().setUseAscender(true);
         tablaOrdenes.getDefaultCell().setUseDescender(true);
         Font f2 = new Font();
         f2.setColor(Color.WHITE);
         PdfPCell cell2 = new PdfPCell(new Phrase("Ordenes de trabajo", f2));
         cell2.setBackgroundColor(Color.BLACK);
         cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell2.setColspan(4);
         tablaOrdenes.addCell(cell2);
         tablaOrdenes.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);
         tablaOrdenes.addCell("No.");
         tablaOrdenes.addCell("Descripcion");
         tablaOrdenes.addCell("Planta");
         tablaOrdenes.addCell("Precio");
         tablaOrdenes.getDefaultCell().setBackgroundColor(null);
         for (PedidoOrden orden : pedido.getOrdenes()) {
            tablaOrdenes.addCell("" + orden.getOrdenTrabajo().getLlave().getNumero());
            tablaOrdenes.addCell(orden.getOrdenTrabajo().getDescripcion());
            tablaOrdenes.addCell(orden.getOrdenTrabajo().getPlanta().getDescripcionCorta());
            double precioOT = 0;
            List<TrabajoRealizado> trabajosRealizados = orden.getOrdenTrabajo().getTrabajosRealizados();
            for (TrabajoRealizado trabajo : trabajosRealizados) {
               precioOT += trabajo.getPrecio();
            }
            tablaOrdenes.addCell("" + precioOT);
         }
         documentoPDF.add(tablaOrdenes);

         PdfPTable tablaFacturas = new PdfPTable(new float[]{2, 2, 2, 2, 2, 2, 2, 2});
         tablaFacturas.setWidthPercentage(100f);
         tablaFacturas.getDefaultCell().setUseAscender(true);
         tablaFacturas.getDefaultCell().setUseDescender(true);
         Font f4 = new Font();
         f4.setColor(Color.WHITE);
         PdfPCell cell4 = new PdfPCell(new Phrase("Facturas", f4));
         cell4.setBackgroundColor(Color.BLACK);
         cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell4.setColspan(8);
         tablaFacturas.addCell(cell4);
         tablaFacturas.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);
         tablaFacturas.addCell("No./Folio");
         tablaFacturas.addCell("Concepto");
         tablaFacturas.addCell("Divisa");
         tablaFacturas.addCell("Forma de Pago");
         tablaFacturas.addCell("Fecha Factura");
         tablaFacturas.addCell("Importe S/IVA");
         tablaFacturas.addCell("IVA");
         tablaFacturas.addCell("Total");
         tablaFacturas.getDefaultCell().setBackgroundColor(null);

         for (Factura factura : pedido.getFacturas()) {
            tablaFacturas.addCell(factura.getLlave().getFolio());
            tablaFacturas.addCell(factura.getConcepto());
            tablaFacturas.addCell(factura.getMoneda().getDescripcion());
            tablaFacturas.addCell(factura.getFormaPago());
            tablaFacturas.addCell(factura.getFechaFactura().toString());
            tablaFacturas.addCell("" + factura.getSubtotal());
            tablaFacturas.addCell("" + factura.getMontoIva());
            tablaFacturas.addCell("" + factura.getSubtotal() + factura.getMontoIva());
         }
         documentoPDF.add(tablaFacturas);

         documentoPDF.close();
      } catch (DocumentException ex) {
         ex.printStackTrace();
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
      }
      return rutaArchivoPDF;
   }
}
